require 'fiber'
require File.dirname(__FILE__) + '/../../source/asymy/asymy'
require 'facets' # caller
class ConnectionPool
  def initialize count, opts
    @pool = []
    @waiting = []
    count.times { @pool << Asymy::Connection.new(opts) }
  end

  def go_from_waiting
    return unless @waiting.length > 0
    query, fiber, block = @waiting.shift
    go(query, fiber, block)
  end

  @@sum_within= 0
  def go query, fiber, block
    raise unless @pool.length > 0
    conn = @pool.shift
    @@sum_within += 1
    conn.exec(query) {|*args|
            block.call *args
            @pool << conn # not sure if this is smart, but it cycles connections
            go_from_waiting # pool the next guy -- he'll return control to us
            @@sum_within -= 1
            fiber.resume # release it to continue
    }
  end

  def exec_when_available query, &block
    @waiting << [query, Fiber.current, block]
    if @pool.length > 0
      go_from_waiting
    end
    Fiber.yield # suspend ourselves, as should always happen as we wait for the DB to come and get us when it's done
  end
  
end

class Thread
 def backtrace
  trace = nil
 begin
   raise StandardError
 rescue StandardError => e
  trace = e.backtrace
 end
 trace
 end
end
 
